﻿#include <iostream> 
#include <vector>
#include <opencv2/core.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/imgproc.hpp>
#include <opencv2/xfeatures2d.hpp>

using namespace cv;
using namespace std;


int surf()
{
	Mat image01 = imread("book_left.jpg", 1);    //右图
	Mat image02 = imread("book_right.jpg", 1);    //左图
	namedWindow("p2", 0);
	namedWindow("p1", 0);
	imshow("p2", image01);
	imshow("p1", image02);

	//灰度图转换  
	Mat image1, image2;
	cvtColor(image01, image1, CV_RGB2GRAY);
	cvtColor(image02, image2, CV_RGB2GRAY);

	Ptr<Feature2D> surf = xfeatures2d::SURF::create(800);
	//提取特征点    
	//SurfFeatureDetector surfDetector(800);  // 海塞矩阵阈值，在这里调整精度，值越大点越少，越精准 
	vector<KeyPoint> keyPoint1, keyPoint2;
	//surfDetector.detect(image1, keyPoint1);
	//surfDetector.detect(image2, keyPoint2);

	//特征点描述，为下边的特征点匹配做准备    
	//SurfDescriptorExtractor SurfDescriptor;
	Mat imageDesc1, imageDesc2;
	//SurfDescriptor.compute(image1, keyPoint1, imageDesc1);
	//SurfDescriptor.compute(image2, keyPoint2, imageDesc2);

	surf->detectAndCompute(image01, Mat(), keyPoint1, imageDesc1);
	surf->detectAndCompute(image02, Mat(), keyPoint2, imageDesc2);

	//获得匹配特征点，并提取最优配对     
	FlannBasedMatcher matcher;
	vector<DMatch> matchePoints;

	matcher.match(imageDesc1, imageDesc2, matchePoints, Mat());
	cout << "total match points: " << matchePoints.size() << endl;


	Mat img_match;
	drawMatches(image01, keyPoint1, image02, keyPoint2, matchePoints, img_match);
	namedWindow("match", 0);
	imshow("match", img_match);
	imwrite("match.jpg", img_match);

	waitKey();
	return 0;
}


int surf_opt()
{
	Mat image01 = imread("book_left.jpg", 1);    //右图
	Mat image02 = imread("book_right.jpg", 1);    //左图
	namedWindow("p2", 0);
	namedWindow("p1", 0);
	imshow("p2", image01);
	imshow("p1", image02);

	//灰度图转换  
	Mat image1, image2;
	cvtColor(image01, image1, CV_RGB2GRAY);
	cvtColor(image02, image2, CV_RGB2GRAY);

	Ptr<Feature2D> surf = xfeatures2d::SURF::create(2000);
	//提取特征点    
	//SurfFeatureDetector surfDetector(800);  // 海塞矩阵阈值，在这里调整精度，值越大点越少，越精准 
	vector<KeyPoint> keyPoint1, keyPoint2;
	//surfDetector.detect(image1, keyPoint1);
	//surfDetector.detect(image2, keyPoint2);

	//特征点描述，为下边的特征点匹配做准备    
	//SurfDescriptorExtractor SurfDescriptor;
	Mat imageDesc1, imageDesc2;
	//SurfDescriptor.compute(image1, keyPoint1, imageDesc1);
	//SurfDescriptor.compute(image2, keyPoint2, imageDesc2);

	surf->detectAndCompute(image01, Mat(), keyPoint1, imageDesc1);
	surf->detectAndCompute(image02, Mat(), keyPoint2, imageDesc2);

	FlannBasedMatcher matcher;
	vector<vector<DMatch> > matchePoints;
	vector<DMatch> GoodMatchePoints;

	vector<Mat> train_desc(1, imageDesc1);
	matcher.add(train_desc);
	matcher.train();

	matcher.knnMatch(imageDesc2, matchePoints, 2);
	cout << "total match points: " << matchePoints.size() << endl;

	// Lowe's algorithm,获取优秀匹配点
	for (int i = 0; i < matchePoints.size(); i++)
	{
		if (matchePoints[i][0].distance < 0.6 * matchePoints[i][1].distance)
		{
			GoodMatchePoints.push_back(matchePoints[i][0]);
		}
	}

	Mat first_match;
	drawMatches(image02, keyPoint2, image01, keyPoint1, GoodMatchePoints, first_match);
	imshow("first_match ", first_match);
	waitKey();
	return 0;
}